package com.onpositive.data.serializer.readers;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
import java.util.BitSet;
import java.util.LinkedHashSet;

import com.onpositive.data.AbstractReader;
import com.onpositive.data.serializer.writers.AbstractWriter;
import com.onpositive.data.serializer.writers.ByteArrayWriter;

public class ByteArrayReader extends AbstractReader<byte[]>{

	private static final int INT_SIZE = 4;
	
	private int[] offsets ;
	
	public ByteArrayReader() {
		super( byte[].class );
	}
	@Override
	public AbstractWriter<byte[]> getWriter() {
		return new ByteArrayWriter();
	}

	@Override
	public synchronized byte[] getObject(int i) {
		
		if( !isInitialized() )
			init() ;

		try {
			if (offsets.length==0){
				doInit();
			}
			int valueStart = offsets[i] ;
			int length = offsets[i+1] - valueStart ;
			
			if( length == 0 )
				return null ;
			
			this.file.seek( collectionStart + myStart + valueStart ) ;
				
			byte[] result = new byte[ length ] ;
			this.file.read( result, 0 ,length ) ;
			//doTest( result, i ) ;
			 
			return result ;
			
		} catch (IOException e) {
			e.printStackTrace();
			return null ;
		}
	}

	@Override
	protected synchronized void doInit() {
		
		int initialReadSize = INT_SIZE * 2 ; 
		
		try {			
			this.file.seek( collectionStart + myStart + INT_SIZE ) ; //also skip writerID
			
			byte[] byteArr = new byte[ initialReadSize ] ;
			
			file.read( byteArr, 0, initialReadSize ) ;
			ByteBuffer bBuf = ByteBuffer.wrap( byteArr ) ;
			IntBuffer iBuf = bBuf.asIntBuffer() ;
			
			iBuf.get() ;
			int offsetsSize = iBuf.get() ;
			offsets = new int[ offsetsSize ] ;

			byteArr = new byte[ INT_SIZE * offsetsSize ] ;
			file.read( byteArr, 0, INT_SIZE * offsetsSize ) ;
			bBuf = ByteBuffer.wrap( byteArr ) ;
			iBuf = bBuf.asIntBuffer() ;
				
			for( int i = 0 ; i < offsetsSize ; i++ )
				offsets[i] = iBuf.get() ;
			
		}
		catch (IOException e) {
			e.printStackTrace();
			return ;
		}	
	}

	@Override
	public void filterOut(LinkedHashSet<Object> obj, String text) {
		//do nothing
	}


	@Override
	public boolean accept(int op, int a, Object constraint) {
		return false;
	}


	@Override
	public Object aggregate(int op, BitSet ss) {
		return null;
	}

	@Override
	public void setValue(int num, Object value) {
		throw new UnsupportedOperationException();
	}
	@Override
	public void initEmpty(int dataSize) {
		offsets=new int[dataSize*2];
		this.setInitialized();
	}
	@Override
	public void expand(int newSize) {
		throw new UnsupportedOperationException();
	}

}
